#ifndef CollView_First
#define CollView_First
#ifdef __GNUG__
#pragma interface
#endif

#include "View.h"

class SeqCollection;

//---- CollectionView options --------------------------------------------------

enum CollViewOptions {
	eCVGrid             = BIT(eViewLast+1),
	eCVDontStuckToBorder= BIT(eViewLast+2),
	eCVExpandRows       = BIT(eViewLast+3),
	eCVExpandCols       = BIT(eViewLast+4),
	eCVModified         = BIT(eViewLast+5),
	eCVDefault          = 0,
	eCVLast             = eViewLast + 5
};

//---- CollectionView ----------------------------------------------------------

class CollectionView: public View {
protected:
	SeqCollection *coll;
	Rectangle selection;
	Point gap, minExtent;
	int *xPos, *yPos, rows, cols;
	VObject *defaultItem;

public:
	MetaDef(CollectionView);

	CollectionView(EvtHandler*, SeqCollection*, CollViewOptions o= eCVDefault,
														int r= 0, int c= 1);
	~CollectionView();

	void SetCollection(SeqCollection*, bool freeold= TRUE);
	SeqCollection *GetCollection()
		{ return coll; }
	void SetDefaultItem(VObject *d);
	void SetColsRows(const Point &cr);

	//---- layout
	void SetMinExtent(Point);
	Metric GetMinSize();
	void SetOrigin(Point at);
	void SetGap(const Point &g)
		{ gap= g; }
	void Update();
	void Open(bool m);
		
	//---- drawing
	void Draw(Rectangle);
	virtual void DrawGrid(Point from, Point to);

	//---- event handling
	Command *DoLeftButtonDownCommand(Point, Token, int);
	Command *DoKeyCommand(int, Token);
	virtual void DoSelect(Rectangle sel, int clicks);
	VObject *Detect(BoolFun find, void *arg);

	//---- updating (change propagation)
	void DoObserve(int, int, void*, Object*);
	void Modified();

	//---- selection
	Rectangle GetSelection()
		{ return selection; }
	void SetSelection(const Rectangle &r, bool sendcontrol= FALSE);
	void ClearSelection(bool redraw= TRUE);
		
	//---- mapping
	Point PointToItem(const Point &pos, bool *outside= 0);
	Rectangle ItemRect(int x, int y);
	Rectangle ItemRect(const Point &item)
		{ return ItemRect(item.x, item.y); }
	VObject *GetItem(int x, int y);
	Point ItemPos(VObject*);
	Rectangle ItemRect(const Rectangle &r);
	void InvalidateItemRect(const Rectangle &r)
		{ InvalidateRect(ItemRect(r)); }
	void ConstrainScroll(Point*);
	void CalcScrollStep(Point &delta, const Point &relOrigin, const Point &scroll);

	//---- input/output
	OStream& PrintOn(OStream&);
	IStream& ReadFrom(IStream&);
	bool PrintOnWhenObserving(Object*);

	//---- inspecting
	void CollectParts(Collection*);
};

//---- CellSelector ------------------------------------------------------------

class CellSelector: public Command {
	CollectionView *lvp;
	VObject *itemptr, *last;
	Point item;
	bool dontstuck;
public:
	CellSelector(CollectionView*, bool dontstucktoborder);
	void TrackFeedback(Point, Point, bool);
	Command *TrackMouse(TrackPhase, Point, Point, Point);
};

#endif

